package net.zoneland.zrdp.framework.interceptor;



import net.zoneland.zrdp.framework.manager.AsyncSequentialExecute;
import net.zoneland.zrdp.framework.manager.factory.AsyncFactory;
import net.zoneland.zrdp.system.domain.SysHttpLog;

import org.apache.http.*;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;

public class DatabaseLoggingInterceptor implements HttpRequestInterceptor, HttpResponseInterceptor {

    private static final Set<String> TEXT_CONTENT_TYPE = Collections.unmodifiableSet(
        new HashSet<>(Arrays.asList(
            "application/json", "application/xml", "text/html", "text/plain", "text/xml"
        ))
    );

    // HttpRequestInterceptor 的实现
    @Override
    public void process(final HttpRequest request, final HttpContext context) throws IOException {
        final SysHttpLog httpLog = new SysHttpLog();
        // 存储请求的起始时间
        final LocalDateTime startTime = LocalDateTime.now();
        final String uuid = UUID.randomUUID().toString();
        context.setAttribute("startTime", startTime);
        context.setAttribute("httpLogUuid", uuid);
        httpLog.setStartTime(startTime);
        httpLog.setUuid(uuid);
        // 存储请求的URI和方法
        if (request instanceof HttpUriRequest) {
            final HttpUriRequest uriRequest = (HttpUriRequest) request;
            final String requestURI = uriRequest.getURI().toString();
            final String httpMethod = uriRequest.getMethod();
            context.setAttribute("requestURI", requestURI);
            httpLog.setUrl(requestURI);
            if (!requestURI.startsWith("http")) {
                final String url = context.getAttribute(HttpCoreContext.HTTP_TARGET_HOST).toString() + requestURI;
                context.setAttribute("requestURI", url);
                httpLog.setUrl(url);
            }
            context.setAttribute("httpMethod", httpMethod);
            httpLog.setHttpMethod(httpMethod);

        }

        // 存储请求的参数
        // 如果请求包含实体，则记录实体内容（排除文件）
        if (request instanceof HttpEntityEnclosingRequest) {
            final HttpEntityEnclosingRequest entityRequest = (HttpEntityEnclosingRequest) request;
            final HttpEntity entity = entityRequest.getEntity();
            final ContentType contentType = ContentType.getOrDefault(entity);
            // 检查是否为多部分实体
            if (TEXT_CONTENT_TYPE.contains(contentType.getMimeType().toLowerCase())) {
                // 对于非文件上传请求，记录整个实体
                final String entityContent = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                context.setAttribute("requestParameters", entityContent);
                httpLog.setParameters(entityContent);
            }
        }


        AsyncSequentialExecute.me().execute(AsyncFactory.recordHttpClientLog(httpLog));
    }

    // HttpResponseInterceptor 的实现
    @Override
    public void process(final HttpResponse response, final HttpContext context) throws IOException {
        // 获取响应状态码
        final int statusCode = response.getStatusLine().getStatusCode();

        // 检索存储的请求信息
        final LocalDateTime startTime = (LocalDateTime) context.getAttribute("startTime");
        final String uuid = (String) context.getAttribute("httpLogUuid");
        final String requestURI = (String) context.getAttribute("requestURI");
        final String httpMethod = (String) context.getAttribute("httpMethod");
        final String requestParameters = (String) context.getAttribute("requestParameters");
        // 计算请求的持续时间
        final LocalDateTime endTime = LocalDateTime.now();
        final long duration = ChronoUnit.MILLIS.between(startTime, endTime);
        // 执行数据库记录操作
        final SysHttpLog httpLog = new SysHttpLog();
        if (response.getEntity() != null) {
            final ContentType contentType = ContentType.getOrDefault(response.getEntity());
            if (TEXT_CONTENT_TYPE.contains(contentType.getMimeType().toLowerCase())) {
                // 复制响应实体
                final String body = EntityUtils.toString(response.getEntity());
                // 这里可以根据需要处理 body
                httpLog.setResultText(body);
                // 使用相同的内容创建一个新的 StringEntity，并替换原始响应实体
                // 确保使用正确的字符编码
                final Charset charset = contentType.getCharset() != null ? contentType.getCharset() : StandardCharsets.UTF_8;
                response.setEntity(new StringEntity(body, charset));
            }

        }

        httpLog.setUuid(uuid);
        httpLog.setDuration(duration);
        httpLog.setHttpMethod(httpMethod);
        httpLog.setUrl(requestURI);
        httpLog.setParameters(requestParameters);
        httpLog.setStatusCode((long) statusCode);
        httpLog.setStartTime(startTime);
        AsyncSequentialExecute.me().execute(AsyncFactory.updateHttpClientLog(httpLog));
    }

}

